package com.jm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jm.common.exception.ServiceException;
import com.jm.dao.OrderMapper;
import com.jm.pojo.*;
import com.jm.pojo.dto.OrdersDto;
import com.jm.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private UserService userService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private OrderDetailService orderDetailService;


    @Override
    public <E extends IPage<Orders>> E page(E page) {
        return super.page(page);
    }

    @Override
    public IPage<OrdersDto> selectByCondition(Long page, Long pageSize, String number, LocalDateTime beginTime, LocalDateTime endTime) {
        IPage<Orders> pager = new Page<>(page, pageSize);
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<Orders>();
        lqw.eq(number != null, Orders::getNumber, number);
        if (beginTime != null && endTime != null) {
            lqw.between(Orders::getCheckoutTime, beginTime, endTime);
        }
//        进行查询
        page(pager, lqw);
        pager.setRecords(
//                设置用户名称的数据
                pager.getRecords().stream().map((order) -> {
                    String name = userService.getById(order.getUserId()).getName();
                    order.setUserName(name);
                    return order;
                }).collect(Collectors.toList()));
        return entityTransformToIPage(pager);
    }

    /**
     * 用户下单的处理
     *
     * @param orders 订单对象
     */
    @Override
    public void submit(Orders orders) {
        Long phone = orders.getUserId();
        User user = userService.getUserByPhone(phone.toString());
//        查询购物车数据
        LambdaQueryWrapper<ShoppingCart> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ShoppingCart::getUserId, user.getId());
        List<ShoppingCart> list = shoppingCartService.list(lqw);
        if (list == null || list.size() == 0) throw new ServiceException("购物车没有数据");
//        查询用户数据
        if (user == null) throw new ServiceException("未查询到用户数据");
//        查询地址数据
        Long addressBookId = orders.getAddressBookId();
        AddressBook addressBook = addressBookService.getById(addressBookId);
        if (addressBook == null) throw new ServiceException("未获取到地址数据");
//        设置参数
        long orderId = IdWorker.getId();//订单号

        AtomicInteger amount = new AtomicInteger(0);

        List<OrderDetail> orderDetailList = list.stream().map((item) -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            orderDetail.setNumber(item.getNumber());
            orderDetail.setToyId(item.getToyId());
            orderDetail.setSetmealId(item.getSetmealId());
            orderDetail.setName(item.getName());
            orderDetail.setImage(item.getImage());
            orderDetail.setAmount(item.getAmount());
            amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());
            return orderDetail;
        }).collect(Collectors.toList());

        orders.setId(orderId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setStatus(2);
        orders.setAmount(new BigDecimal(amount.get()));
        orders.setUserId(user.getId());

        orders.setNumber(String.valueOf(orderId));
        orders.setUserName(user.getName());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        /*orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
                + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
                + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
                + (addressBook.getDetail() == null ? "" : addressBook.getDetail()));*/
        orders.setAddress((addressBook.getDetail() == null ? "" : addressBook.getDetail()));
//        保存订单数据
        this.save(orders);
//        增加订单明细数据
        orderDetailService.saveBatch(orderDetailList);
//        清空购物车
        shoppingCartService.remove(lqw);
    }


    /**
     * 修改派送状态
     */
    @Override
    public boolean status(Orders orders) {
        Long id = orders.getId();
        Integer status = orders.getStatus();
        LambdaUpdateWrapper<Orders> luw = new LambdaUpdateWrapper<Orders>();
        luw.eq(true, Orders::getId, id);
        luw.set(true, Orders::getStatus, status);
        return update(luw);
    }

    private IPage<OrdersDto> entityTransformToIPage(IPage<Orders> orderPage) {
//        得到订单数据
        List<Orders> orderRecords = orderPage.getRecords();
//        将其转为包含订单细节的集合
        List<OrdersDto> dishDtos = getDishDtos(orderRecords);
        IPage<OrdersDto> orderDtoPage = new Page<>();
//        复制原dto
        BeanUtils.copyProperties(orderPage, orderDtoPage, "records");
//        替代Redoers数据返回
        orderDtoPage.setRecords(dishDtos);
        return orderDtoPage;
    }

    private List<OrdersDto> getDishDtos(List<Orders> list) {
        List<OrdersDto> collect = list.stream().map((item) -> {
            return setDtoProperties(item);
        }).collect(Collectors.toList());
        return collect;
    }

    private OrdersDto setDtoProperties(Orders item) {
        Long id = item.getId();
        LambdaQueryWrapper<OrderDetail> lqw = new LambdaQueryWrapper<>();
        lqw.eq(true, OrderDetail::getOrderId, id);
        List<OrderDetail> list = orderDetailService.list(lqw);
        OrdersDto ordersDto = new OrdersDto();
        BeanUtils.copyProperties(item, ordersDto);
        ordersDto.setOrderDetails(list);
        return ordersDto;
    }
}
